Skip to main content

Cash Out — Confirmation

Finalize an earnings payout. Presto debits the driver's available earnings and records the institution as the paying party.

info

Call this only after a successful Cash Out — Initialization and after the driver has supplied the OTP from the Presto driver app.

Overview​

Confirmation is the point of no return for a Cash Out. On 200 OK:

  • The driver's available_earnings is permanently reduced by amount
  • A payout record is created against your institution for reconciliation
  • The driver receives a notification in the Presto driver app

Hand over the cash only after you receive 200 OK.

Endpoint details​

Method: POST URL: /api/institutions/v1/drivers/earnings/payout/confirm Purpose: Debit the driver's earnings and record the payout

Authentication required

All API calls require a valid bearer token. See Authentication.

Request specification​

Headers​

HeaderRequiredDescription
AuthorizationYesBearer {token}
Content-TypeYesapplication/json
Idempotency-KeyYesUUID v4. Replaying the same key returns the original response instead of paying out twice.

Request body​

ParameterTypeRequiredDescription
transaction_referencestringYesThe reference returned by the init call
otpstringConditionalThe code the driver received in the Presto app. Required when otp_required was true on init

Example request​

// Headers:
// Authorization: Bearer {token}
// Content-Type: application/json
// Idempotency-Key: 2c1d4e6a-77b8-4c9d-91ef-5a3b7c8d9e01

{
"transaction_reference": "EP-4T7M1XC9QD",
"otp": "418320"
}

Response specification​

Success response​

200 OK
{
"data": {
"status": "completed",
"type": "earnings_payout",
"transaction_reference": "EP-4T7M1XC9QD",
"amount": 100.000,
"currency": "LYD",
"timestamp": "2026-09-14T14:35:12Z",
"institution_reference": "IZI-2026-0914-000188",
"driver": {
"uid": "10432",
"name": "MOH... OK...",
"phone": "218920000000"
},
"available_earnings_after": 28.750
}
}

Response fields​

FieldTypeDescription
statusstring"completed"
typestringAlways "earnings_payout"
transaction_referencestringReference of the completed payout
amountnumberAmount paid out
currencystringCurrency of the amount
timestampstringISO 8601 date and time the payout was recorded
institution_referencestringYour own reference from the init call, echoed back unchanged
driverobjectDriver whose earnings were debited
available_earnings_afternumberRemaining earnings after the payout

Error responses​

404 Not Found
{
"message": "Transaction reference not found"
}

409 Conflict — already finalized

{
"message": "Transaction is not pending"
}

410 Gone — hold expired

{
"message": "Transaction has expired"
}

422 Unprocessable Content — wrong OTP

{
"message": "The provided OTP is invalid.",
"errors": {
"otp": [
"The provided OTP is invalid."
]
},
"attempts_remaining": 2
}

429 Too Many Requests — OTP attempts exhausted

{
"message": "Too many invalid OTP attempts. The transaction has been voided."
}

422 Unprocessable Content — the driver's earnings changed since init

{
"message": "The amount may not be greater than the available earnings.",
"errors": {
"amount": [
"The amount may not be greater than the available earnings."
]
}
}
500 Internal Server Error
{
"message": "Transaction processing failed"
}

Error handling​

Common errors
HTTP StatusError TypeExample MessageWhen it Occurs / Resolution
404Not found{"message": "Transaction reference not found"}Wrong or unknown reference. Do not pay.
409Not pending{"message": "Transaction is not pending"}Already confirmed or voided. Query transaction status to find out which.
410Expired{"message": "Transaction has expired"}More than 15 minutes since init. Re-run init.
422Invalid OTP{"message": "The provided OTP is invalid.", "attempts_remaining": 2}Ask the driver to re-read the code. The hold stays active until attempts run out or the ttl passes.
429OTP attempts exhausted{"message": "Too many invalid OTP attempts. The transaction has been voided."}The hold is released. Start again with a new init.
422Balance changed{"message": "The amount may not be greater than the available earnings."}The driver's earnings were reduced through another channel after init. The transaction is now failed. Do not pay.
500Internal server error{"message": "Transaction processing failed"}Outcome unknown. Query transaction status before paying.
Never pay out on an unknown outcome

If confirm times out, the payout may or may not have been recorded. Query transaction status with the same transaction_reference and pay only if it reports completed. Retrying confirm is safe only with the same Idempotency-Key.

Implementation tips​

Best practices
  • Allow up to 3 OTP attempts in your teller interface and surface attempts_remaining to the teller.
  • Record transaction_reference, timestamp and available_earnings_after against your own receipt for end-of-day reconciliation.
  • Print a receipt showing the Presto reference so the driver can raise a dispute with either party.
  • Use exponential backoff for 5xx retries, always with the same idempotency key.

Next steps​

Verify or reconcile the payout with the Transaction Status endpoint.